//合成条件判断函数
//combinecondition.h

#ifndef COMBINE_CONDITION_H
#define COMBINE_CONDITION_H
#include "spdlog/spdlog.h"
#include "spdlog/sinks/daily_file_sink.h"

#include <vector>
#include <string>

using std::vector;
using std::string;

const int MONTH_LEAST_DAY = 20 ; 

//判断合成触发条件是否成立
//判断满足进行合成的条件需要同时满足：
//1 合成的时间范围必须在当天之前 ， 比如2月1日才有可能合成1月的月产品 (这个不需要考虑）
//2 全部的文件列表中必须有超过合成区间后一天的数据，比如合成1月产品，
//  那么整个文件列表必须要有1月31日及之后的文件到位才行，这样才说明1月的数据都到齐了，
//  即使有可能中间缺少了个别天。
//3 月数据合成必须要有20天月内数据，季合成必须有三个月的数据，年数据必须要12月数据。
bool isMonthCombineConditionOk( 
    const int endYmdAll,              //全部文件的结束时间
    const vector<int>& allfilesYmd ,  //全部文件日期数组
    const vector<string>& allfiles ,  //全部文件的路径，用于选中的提出到pickFiles
    const int targetYear ,  //YYYY
    const int targetMonth , //1-12
    vector<string>& pickFiles         //选出有待合成的文件路径数组
    )
{
    int pickstart = ( targetYear * 100 + targetMonth )* 100 +1 ;
    int pickend = ( targetYear * 100 + targetMonth )* 100 +31 ;
    
    if( endYmdAll < pickend ) return false ;
    
    pickFiles.clear() ;
    for(size_t it = 0 ; it < allfilesYmd.size() ; ++ it ){
        if( allfilesYmd[it] >= pickstart && allfilesYmd[it] <= pickend ){
            pickFiles.push_back( allfiles[it]) ;
        }
    }
    
    if( pickFiles.size() >= MONTH_LEAST_DAY ){
        return true ;
    }else{
        spdlog::info("isMonthCombineConditionOk target {}-{} pickFiles {} less than {}.",
            targetYear , targetMonth , pickFiles.size() , MONTH_LEAST_DAY ) ;
        return false ;
    }
}

bool isSeasonCombineConditionOk( 
    const int endYmdAll,              //全部文件的结束时间
    const vector<int>& allfilesYmd ,  //全部文件日期数组
    const vector<string>& allfiles ,  //全部文件的路径，用于选中的提出到pickFiles
    const int targetYear ,  //YYYY
    const int targetMonth , //3,6,9,12
    vector<string>& pickFiles         //选出有待合成的文件路径数组
    )
{
    int pickstart = 0;
    int pickend = 0; 
    if( targetMonth == 3 ){
        pickstart = (targetYear*100+3)*100+1 ;//20000301
        pickend =  (targetYear*100+5)*100+1 ;//20000501
    }else if( targetMonth==6 ){
        pickstart = (targetYear*100+6)*100+1 ;
        pickend =  (targetYear*100+8)*100+1 ;
    }else if( targetMonth==9 ){
        pickstart = (targetYear*100+9)*100+1 ;
        pickend =  (targetYear*100+11)*100+1 ;
    }else if( targetMonth==12 ){
        pickstart = (targetYear*100+12)*100+1 ;
        pickend =  ( (targetYear+1)*100+2)*100+1 ;
    }else{
        return false ;
    }
    
    if( endYmdAll < pickend ) return false ;
    
    pickFiles.clear() ;
    for(size_t it = 0 ; it < allfilesYmd.size() ; ++ it ){
        if( allfilesYmd[it] >= pickstart && allfilesYmd[it] <= pickend ){
            pickFiles.push_back( allfiles[it]) ;
        }
    }
    
    if( pickFiles.size() == 3 ){
        return true ;
    }else{
        spdlog::info("isSeasonCombineConditionOk target {}-{} pickFiles {} not equal 3.",
            targetYear , targetMonth , pickFiles.size()  ) ;
        return false ;
    }
}

bool isYearCombineConditionOk( 
    const int endYmdAll,              //全部文件的结束时间
    const vector<int>& allfilesYmd ,  //全部文件日期数组
    const vector<string>& allfiles ,  //全部文件的路径，用于选中的提出到pickFiles
    const int targetYear ,  //YYYY
    vector<string>& pickFiles         //选出有待合成的文件路径数组
    )
{
    int pickstart = targetYear*10000 + 101 ;
    int pickend = targetYear*10000 + 1201  ; 
    
    
    if( endYmdAll < pickend ) return false ;
    
    pickFiles.clear() ;
    for(size_t it = 0 ; it < allfilesYmd.size() ; ++ it ){
        if( allfilesYmd[it] >= pickstart && allfilesYmd[it] <= pickend ){
            pickFiles.push_back( allfiles[it]) ;
        }
    }
    
    if( pickFiles.size() == 12 ){
        return true ;
    }else{
        spdlog::info("isYearCombineConditionOk target {} pickFiles {} not equal 12.",
            targetYear  , pickFiles.size()  ) ;
        return false ;
    }
}

//是否闰年
bool cc_is_leapyear(int year)
{
  if (year % 400 == 0)
    return true;
  else if (year % 100 == 0)
    return false;
  else if (year % 4 == 0)
    return true;
  else
    return false;
}

int cc_getMonthNDays( int ymdi ){
    int mon = (ymdi%10000)/100 ;
    int year = ymdi/10000 ;
    if( mon==2 ){
        if( cc_is_leapyear(year) ){
            return 29 ;//闰年29
        }else{
            return 28 ;//平年28
        }
        
    }else if( mon==1 || mon==3 || mon==5 || mon==7 || mon==8 || mon==10 || mon==12 ) return 31 ;
    else return 30 ;
}

int cc_getSeasonNDays(int ymdi ){
    int mon = (ymdi%10000)/100 ;
    int year = ymdi/10000 ;
    if( mon==12 ){
        if( cc_is_leapyear(year+1) ){
            return 31+31+29 ;//闰年29
        }else{
            return 31+31+28 ;//平年28
        }
    }else if( mon==3 )
    {
        return 31+30+31 ;//3,4,5
    }else if( mon==6 ){
        return 30+31+31 ;//6,7,8
    }else return 30+31+30 ;//9, 10, 11
}

int cc_getYearNDays(int ymdi ){
    int mon = (ymdi%10000)/100 ;
    int year = ymdi/10000 ;
    if( cc_is_leapyear(year) ){
        return 366;//闰年29
    }else{
        return 365 ;//平年28
    }
}//here

#endif